package com.ctakit.sdk.app;


import android.text.TextUtils;

import com.ctakit.sdk.SdkApplication;
import com.ctakit.sdk.app.util.RequestUtil;
import com.ctakit.sdk.exception.BusinessException;
import com.ctakit.sdk.http.IHttpCallback;
import com.ctakit.sdk.http.OkHttpMethod;
import com.ctakit.sdk.http.okhttp.OkHttpUtils;
import com.ctakit.sdk.http.okhttp.builder.OkHttpRequestBuilder;
import com.ctakit.sdk.http.okhttp.builder.PostFormBuilder;
import com.ctakit.sdk.http.okhttp.builder.PostStringBuilder;
import com.ctakit.sdk.util.JsonUtils;
import com.orhanobut.logger.Logger;

import java.io.File;
import java.io.IOException;
import java.util.Map;
import java.util.TreeMap;

import okhttp3.MediaType;
import okhttp3.Response;

/**
 * Created by lizhenmin on 15/8/28.
 */
public final class HttpUtils {

    /**
     * 请求方式
     **/

    //
    private static OkHttpRequestBuilder builderRequestBuilder(OkHttpMethod httpMethod, String url) {
        OkHttpRequestBuilder okHttpRequestBuilder = null;
        switch (httpMethod) {
            case GET:
                okHttpRequestBuilder = OkHttpUtils.get().url(url);
                break;
            case POST:
                okHttpRequestBuilder = OkHttpUtils.post().url(url);
                break;
            case POST_BODY:
                okHttpRequestBuilder = OkHttpUtils.postString().url(url);
                break;
            case PUT:
                okHttpRequestBuilder = OkHttpUtils.put().url(url);
                break;

            default:
                okHttpRequestBuilder = OkHttpUtils.get().url(url);
                break;
        }
        okHttpRequestBuilder.headers(((BaseApplication)SdkApplication.app()).getGlobalHeaders(false));


        return okHttpRequestBuilder;
    }


    /**
     * Get方式提交,URL中包含查询参数, 格式：http://www.g.cn?search=p&name=s.....
     *
     * @param url 提交地址
     * @return 响应消息
     * @throws BusinessException
     */
    public static String get(String url) throws BusinessException {

        return getByCallBack(url,null);

    }

    public static String get(String url,IHttpCallback httpCallback) throws BusinessException {

        return getByCallBack(url,httpCallback);

    }



    /**
     * Get方式提交,URL中包含查询参数, 格式：http://www.g.cn?search=p&name=s.....
     *
     * @param url 提交地址
     * @return 响应消息
     * @throws BusinessException
     */
    public static String getByCallBack(String url,IHttpCallback httpCallback) throws BusinessException {

        return doExecute(builderRequestBuilder(OkHttpMethod.GET, url),httpCallback);

    }



    /**
     * Get方式提交,URL中不包含查询参数, 格式：http://www.g.cn
     *
     * @param url    提交地址
     * @param params 查询参数集, 键/值对
     * @return 响应消息
     * @throws BusinessException
     */
    public static String get(String url, Map<String, String> params,IHttpCallback httpCallback) throws BusinessException {
        StringBuffer strtTotalURL = new StringBuffer(url);

        if(params!=null&&!params.isEmpty()){
            if (strtTotalURL.indexOf("?") == -1) {
                strtTotalURL.append("?").append(RequestUtil.getUrl(params));
            } else {
                strtTotalURL.append("&").append(RequestUtil.getUrl(params));
            }
        }

        return get(strtTotalURL.toString(),httpCallback);
    }

    /**
     * Post方式提交,URL中不包含提交参数, 格式：http://www.g.cn
     *
     * @param url    提交地址
     * @param params 提交参数集, 键/值对
     * @return 响应消息
     */
    public static String post(String url, Map<String, String> params,IHttpCallback httpCallback) throws BusinessException {
        return post(url, params, false,httpCallback);
    }


    /**
     * Post方式提交,URL中不包含提交参数, 格式：http://www.g.cn
     *
     * @param url    提交地址
     * @param params 提交参数集, 键/值对
     * @return 响应消息
     */
    public static String post(String url, Map<String, String> params, boolean multipartData,IHttpCallback httpCallback) throws BusinessException {


        if (multipartData) {
            PostFormBuilder builder = (PostFormBuilder) builderRequestBuilder(OkHttpMethod.POST, url);
            Map<String, String> formParams = new TreeMap<>();

            if (params != null && params.size() > 0) {
                for (Map.Entry<String, String> map : params.entrySet()) {
                    String[] key = map.getKey().split("\\.");
                    String[] uploadKey = new String[2];
                    String value = map.getValue();
                    if (key.length == 1) {
                        uploadKey[1] = "String";
                        uploadKey[0] = key[0];
                    } else {
                        uploadKey = key;
                    }
                    if (uploadKey[1].equals("String")) {
                        formParams.put(uploadKey[0], value);
                    } else if (uploadKey[1].equals("File")) {

                        if(!TextUtils.isEmpty(value)){
                            String[] filePaths = value.split(";");
                            for (String path:filePaths){
                                File dataFile = new File(path);
                                if (dataFile.exists() && dataFile.isFile()) {
                                    builder.addFile(uploadKey[0], dataFile.getName(), dataFile);
                                }
                            }
                         }

                    }
                }
            }
            return doExecute(builder.params(formParams),httpCallback);
        } else {
            return doExecute(builderRequestBuilder(OkHttpMethod.POST, url).params(params),httpCallback);
        }


    }

    private static String postBody(String url, Map<String, String> params,IHttpCallback httpCallback) throws BusinessException {


        return doExecute(((PostStringBuilder) builderRequestBuilder(OkHttpMethod.POST_BODY, url)).content(JsonUtils.toJson(params)).mediaType(MediaType.parse("application/json; charset=utf-8")),httpCallback);


    }


    /**
     * Post方式提交,URL中不包含提交参数, 格式：http://www.g.cn
     *
     * @param url    提交地址
     * @param params 提交参数集, 键/值对
     * @return 响应消息
     */
    public static String multipartPost(String url, Map<String, String> params,IHttpCallback httpCallback) throws BusinessException {
        return post(url, params, true,httpCallback);
    }

    /**
     * get方式提交，解决SSL双向数字证书认证
     *
     * @param url     提交地址
     * @param bodyStr 提交的数据
     * @return 响应消息
     */


    public static String postBody(String url, String bodyStr, IHttpCallback httpCallback) throws BusinessException {

        return doExecute(((PostStringBuilder) builderRequestBuilder(OkHttpMethod.POST_BODY, url)).content(bodyStr).mediaType(MediaType.parse("application/json; charset=utf-8")),httpCallback);


    }

    public static String doExecute(OkHttpRequestBuilder requestBuilder,IHttpCallback httpCallback) throws BusinessException {

        try {
            return responseToString(requestBuilder.build().execute(),httpCallback);
        } catch (IOException e) {
            throw new BusinessException(BusinessException.errorMsg, BusinessException.errorCode_500);
        }

    }



    private static String responseToString(Response rs,IHttpCallback httpCallback) throws BusinessException, IOException {

            String result = "";

        try {
            if (httpCallback != null) {
                if (!httpCallback.onResponse(rs)) {
                    // return ;
                }
                ;
            }
            if (rs.isSuccessful()) {
                result = rs.body().string();
                return result;
            } else {
                Logger.d("http-error:" + rs.code() + "==" + rs.message());
                if (rs.code() == 600) {
                    throw new BusinessException("版本过低，请升级后使用。", 600);
                } else if (rs.code() == 403) {
                    throw new BusinessException("登录信息已经过期，请重新登录", 403);
                }

                throw new BusinessException(BusinessException.errorMsg, rs.code());

            }

        }catch (Exception e){
            throw new BusinessException(BusinessException.errorMsg, rs.code());
        }finally {
            try {
                if(rs!=null)
                rs.close();
            }catch (Exception e){

            }

        }



    }
}

